<template>
  <div class="redis-monitor-root">
    <!-- 顶部信息卡片区 -->
    <a-row :gutter="[16, 16]" class="overview-row">
      <a-col :span="4"
        ><a-card class="overview-card"
          ><div class="card-title">版本</div>
          <div class="card-value">{{ safe(redisInfo.redisVersion) }}</div></a-card
        ></a-col
      >
      <a-col :span="4"
        ><a-card class="overview-card"
          ><div class="card-title">模式</div>
          <div class="card-value">{{ safe(redisInfo.redisMode) }}</div></a-card
        ></a-col
      >
      <a-col :span="4"
        ><a-card class="overview-card"
          ><div class="card-title">端口</div>
          <div class="card-value">{{ safe(redisInfo.tcpPort) }}</div></a-card
        ></a-col
      >
      <a-col :span="4"
        ><a-card class="overview-card"
          ><div class="card-title">角色</div>
          <div class="card-value">{{ safe(redisInfo.role) }}</div></a-card
        ></a-col
      >
      <a-col :span="4"
        ><a-card class="overview-card"
          ><div class="card-title">运行时长</div>
          <div class="card-value">{{ formatUptime(redisInfo.uptimeInSeconds) }}</div></a-card
        ></a-col
      >
      <a-col :span="4"
        ><a-card class="overview-card"
          ><div class="card-title">主机</div>
          <div class="card-value">{{ safe(redisInfo.host) }}</div></a-card
        ></a-col
      >
    </a-row>

    <!-- 统计区 -->
    <a-row :gutter="[16, 16]" class="group-row">
      <!-- 连接统计 -->
      <a-col :span="8">
        <a-card class="group-card" title="连接统计">
          <div class="chart-area">
            <v-chart :option="connectionBarOption" autoresize style="height: 90px" />
          </div>
          <div class="stat-row" v-for="(v, k) in connectionStats" :key="k">
            <span class="stat-label">{{ statLabels[k] || k }}：</span>
            <span class="stat-value">{{ safe(v) }}</span>
          </div>
        </a-card>
      </a-col>
      <!-- 性能统计 -->
      <a-col :span="8">
        <a-card class="group-card" title="性能统计">
          <div class="chart-area">
            <v-chart :option="performanceLineOption" autoresize style="height: 90px" />
          </div>
          <div class="chart-area">
            <v-chart :option="hitPieOption" autoresize style="height: 90px" />
          </div>
          <div class="stat-row" v-for="(v, k) in performanceStats" :key="k">
            <span class="stat-label">{{ statLabels[k] || k }}：</span>
            <span class="stat-value">{{ safe(v) }}</span>
          </div>
        </a-card>
      </a-col>
      <!-- 内存统计 -->
      <a-col :span="8">
        <a-card class="group-card" title="内存统计">
          <div class="chart-area">
            <v-chart :option="memoryDonutOption" autoresize style="height: 90px" />
          </div>
          <div class="chart-area">
            <v-chart :option="memoryLineOption" autoresize style="height: 90px" />
          </div>
          <div class="stat-row" v-for="(v, k) in memoryStats" :key="k">
            <span class="stat-label">{{ statLabels[k] || k }}：</span>
            <span class="stat-value">{{ safe(v) }}</span>
          </div>
        </a-card>
      </a-col>
    </a-row>
    <a-row :gutter="[16, 16]" class="group-row">
      <!-- 持久化/复制 -->
      <a-col :span="8">
        <a-card class="group-card" title="持久化/复制">
          <div class="stat-row" v-for="(v, k) in persistenceStats" :key="k">
            <span class="stat-label">{{ statLabels[k] || k }}：</span>
            <span class="stat-value">{{ safe(v) }}</span>
          </div>
          <div class="stat-row" v-for="(v, k) in replication" :key="'rep' + k">
            <span class="stat-label">{{ statLabels[k] || k }}：</span>
            <span class="stat-value">{{ safe(v) }}</span>
          </div>
        </a-card>
      </a-col>
      <!-- CPU/网络 -->
      <a-col :span="8">
        <a-card class="group-card" title="CPU/网络">
          <div class="chart-area">
            <v-chart :option="cpuLineOption" autoresize style="height: 90px" />
          </div>
          <div class="chart-area">
            <v-chart :option="networkLineOption" autoresize style="height: 90px" />
          </div>
          <div class="stat-row" v-for="(v, k) in cpuStats" :key="k">
            <span class="stat-label">{{ statLabels[k] || k }}：</span>
            <span class="stat-value">{{ safe(v) }}</span>
          </div>
          <div class="stat-row" v-for="(v, k) in networkStats" :key="'net' + k">
            <span class="stat-label">{{ statLabels[k] || k }}：</span>
            <span class="stat-value">{{ safe(v) }}</span>
          </div>
        </a-card>
      </a-col>
      <!-- Keyspace分布 -->
      <a-col :span="8">
        <a-card class="group-card" title="Keyspace分布">
          <div class="chart-area">
            <v-chart :option="keyspacePieOption" autoresize style="height: 90px" />
          </div>
          <div class="chart-area">
            <v-chart :option="keyspaceBarOption" autoresize style="height: 90px" />
          </div>
          <a-table
            :dataSource="keyspaceTable"
            :columns="keyspaceColumns"
            size="small"
            :pagination="false"
            rowKey="db"
            :locale="{ emptyText: '暂无数据' }"
          />
        </a-card>
      </a-col>
    </a-row>
    <!-- 命令统计Top10 -->
    <a-row :gutter="[16, 16]" class="group-row">
      <a-col :span="12">
        <a-card class="section-card" title="命令调用数Top10">
          <v-chart :option="commandCallBarOption" autoresize style="height: 220px" />
        </a-card>
      </a-col>
      <a-col :span="12">
        <a-card class="section-card" title="命令耗时Top10">
          <v-chart :option="commandUsecBarOption" autoresize style="height: 220px" />
        </a-card>
      </a-col>
    </a-row>
    <!-- 命令统计明细表格 -->
    <a-card class="section-card" title="命令统计明细" style="margin-top: 24px">
      <a-table
        :dataSource="commandTable"
        :columns="commandColumns"
        size="small"
        :pagination="false"
        rowKey="cmd"
        :locale="{ emptyText: '暂无数据' }"
      />
    </a-card>
  </div>
</template>

<script setup lang="ts">
  import { ref, computed, onMounted, onUnmounted, onActivated, onDeactivated } from 'vue'
  import { getRedisMonitorStatus } from '@/api/guanliyuanmokuaijiekou'

  const data = ref<any>({})
  const timer = ref<any>(null)

  const safe = (v: any) => (v === undefined || v === null || v === '' ? '暂无数据' : v)
  function formatUptime(seconds: any) {
    if (!seconds || isNaN(Number(seconds))) return '暂无数据'
    const s = Number(seconds)
    const h = Math.floor(s / 3600)
    const m = Math.floor((s % 3600) / 60)
    const sec = s % 60
    return `${h}小时${m}分${sec}秒`
  }

  const statLabels: Record<string, string> = {
    redisVersion: 'Redis版本',
    redisMode: '模式',
    tcpPort: '端口',
    host: '主机',
    role: '角色',
    uptimeInSeconds: '运行时长',
    connectedClients: '连接数',
    maxClients: '最大连接数',
    blockedClients: '阻塞客户端',
    totalConnectionsReceived: '累计连接',
    rejectedConnections: '拒绝连接',
    totalCommandsProcessed: '命令数',
    instantaneousOpsPerSec: 'OPS',
    keyspaceHits: '命中',
    keyspaceMisses: '未命中',
    expiredKeys: '过期Key',
    evictedKeys: '驱逐Key',
    usedMemory: '内存(B)',
    usedMemoryHuman: '内存',
    usedMemoryPeak: '峰值(B)',
    usedMemoryPeakHuman: '峰值',
    maxMemory: '最大内存',
    maxMemoryHuman: '最大内存',
    memFragmentationRatio: '碎片率',
    rdbLastSaveTime: 'RDB最后保存',
    rdbChangesSinceLastSave: 'RDB变更',
    rdbBgsaveInProgress: 'RDB保存中',
    aofEnabled: 'AOF启用',
    aofRewriteInProgress: 'AOF重写',
    aofCurrentSize: 'AOF当前大小',
    aofBaseSize: 'AOF基线大小',
    db: 'DB',
    keys: '键数',
    expires: '过期',
    avg_ttl: '平均TTL',
    subexpiry: '子过期',
    calls: '调用数',
    usec: '总耗时',
    usec_per_call: '平均耗时',
    rejected_calls: '拒绝',
    failed_calls: '失败',
    usedCpuSys: '系统CPU',
    usedCpuUser: '用户CPU',
    totalNetInputBytes: '输入字节',
    totalNetOutputBytes: '输出字节',
    instantaneousInputKbps: '输入Kbps',
    instantaneousOutputKbps: '输出Kbps',
    masterHost: '主机',
    masterPort: '端口',
    masterLinkStatus: '主链路',
    connectedSlaves: '从节点数',
  }

  const redisInfo = computed(() => data.value.redisInfo || {})
  const connectionStats = computed(() => data.value.connectionStats || {})
  const performanceStats = computed(() => data.value.performanceStats || {})
  const memoryStats = computed(() => data.value.memoryStats || {})
  const persistenceStats = computed(() => data.value.persistenceStats || {})
  const replication = computed(() => data.value.replication || {})
  const cpuStats = computed(() => data.value.cpuStats || {})
  const networkStats = computed(() => data.value.networkStats || {})

  const keyspaceTable = computed(() => {
    const ks = data.value.keyspaceStats || {}
    return Object.keys(ks).map(db => ({ db, ...ks[db] }))
  })
  const keyspaceColumns = [
    { title: 'DB', dataIndex: 'db', key: 'db' },
    { title: '键数', dataIndex: 'keys', key: 'keys' },
    { title: '过期', dataIndex: 'expires', key: 'expires' },
    { title: '平均TTL', dataIndex: 'avg_ttl', key: 'avg_ttl' },
    { title: '子过期', dataIndex: 'subexpiry', key: 'subexpiry' },
  ]
  const commandTable = computed(() => {
    const cs = data.value.commandStats || {}
    return Object.keys(cs).map(cmd => ({ cmd, ...cs[cmd] }))
  })
  const commandColumns = [
    { title: '命令', dataIndex: 'cmd', key: 'cmd' },
    { title: '调用数', dataIndex: 'calls', key: 'calls' },
    { title: '总耗时', dataIndex: 'usec', key: 'usec' },
    { title: '平均耗时', dataIndex: 'usec_per_call', key: 'usec_per_call' },
    { title: '拒绝', dataIndex: 'rejected_calls', key: 'rejected_calls' },
    { title: '失败', dataIndex: 'failed_calls', key: 'failed_calls' },
  ]

  // 连接统计 柱状图
  const connectionBarOption = computed(() => {
    const stats = connectionStats.value
    return {
      tooltip: { trigger: 'axis' },
      xAxis: {
        type: 'category',
        data: ['连接数', '最大连接数', '阻塞客户端', '累计连接', '拒绝连接'],
      },
      yAxis: { type: 'value' },
      series: [
        {
          data: [
            Number(stats.connectedClients || 0),
            Number(stats.maxClients || 0),
            Number(stats.blockedClients || 0),
            Number(stats.totalConnectionsReceived || 0),
            Number(stats.rejectedConnections || 0),
          ],
          type: 'bar',
          itemStyle: { color: '#1890ff' },
          barWidth: 28,
        },
      ],
      grid: { left: 20, right: 20, top: 30, bottom: 20 },
    }
  })

  // 性能统计 折线图（命令数、OPS、命中、未命中、过期Key）
  const performanceLineOption = computed(() => {
    const stats = performanceStats.value
    return {
      tooltip: { trigger: 'axis' },
      legend: { data: ['命令数', 'OPS', '命中', '未命中', '过期Key'] },
      xAxis: { type: 'category', data: ['当前'] },
      yAxis: { type: 'value' },
      series: [
        {
          name: '命令数',
          type: 'line',
          data: [Number(stats.totalCommandsProcessed || 0)],
          itemStyle: { color: '#0057b8' },
        },
        {
          name: 'OPS',
          type: 'line',
          data: [Number(stats.instantaneousOpsPerSec || 0)],
          itemStyle: { color: '#36cfc9' },
        },
        {
          name: '命中',
          type: 'line',
          data: [Number(stats.keyspaceHits || 0)],
          itemStyle: { color: '#52c41a' },
        },
        {
          name: '未命中',
          type: 'line',
          data: [Number(stats.keyspaceMisses || 0)],
          itemStyle: { color: '#faad14' },
        },
        {
          name: '过期Key',
          type: 'line',
          data: [Number(stats.expiredKeys || 0)],
          itemStyle: { color: '#f5222d' },
        },
      ],
      grid: { left: 20, right: 20, top: 30, bottom: 20 },
    }
  })
  // 性能统计 命中率饼图
  const hitPieOption = computed(() => {
    const stats = performanceStats.value
    const hit = Number(stats.keyspaceHits || 0)
    const miss = Number(stats.keyspaceMisses || 0)
    return {
      tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
      legend: { show: false },
      series: [
        {
          type: 'pie',
          radius: ['60%', '80%'],
          label: { show: true, formatter: '{b}: {d}%' },
          data: [
            { value: hit, name: '命中', itemStyle: { color: '#52c41a' } },
            { value: miss, name: '未命中', itemStyle: { color: '#faad14' } },
          ],
        },
      ],
    }
  })

  // 内存统计 环形图
  const memoryDonutOption = computed(() => {
    const stats = memoryStats.value
    return {
      tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
      legend: { show: false },
      series: [
        {
          type: 'pie',
          radius: ['60%', '80%'],
          label: { show: true, formatter: '{b}: {d}%' },
          data: [
            { value: Number(stats.usedMemory || 0), name: '已用', itemStyle: { color: '#0057b8' } },
            {
              value: Number(stats.usedMemoryPeak || 0),
              name: '峰值',
              itemStyle: { color: '#36cfc9' },
            },
            { value: Number(stats.maxMemory || 0), name: '最大', itemStyle: { color: '#faad14' } },
          ],
        },
      ],
    }
  })
  // 内存统计 折线图（仅当前快照，后续可做趋势）
  const memoryLineOption = computed(() => {
    const stats = memoryStats.value
    return {
      tooltip: { trigger: 'axis' },
      legend: { data: ['已用', '峰值', '最大'] },
      xAxis: { type: 'category', data: ['当前'] },
      yAxis: { type: 'value' },
      series: [
        {
          name: '已用',
          type: 'line',
          data: [Number(stats.usedMemory || 0)],
          itemStyle: { color: '#0057b8' },
        },
        {
          name: '峰值',
          type: 'line',
          data: [Number(stats.usedMemoryPeak || 0)],
          itemStyle: { color: '#36cfc9' },
        },
        {
          name: '最大',
          type: 'line',
          data: [Number(stats.maxMemory || 0)],
          itemStyle: { color: '#faad14' },
        },
      ],
      grid: { left: 20, right: 20, top: 30, bottom: 20 },
    }
  })

  // Keyspace分布 饼图
  const keyspacePieOption = computed(() => {
    const ks = data.value.keyspaceStats || {}
    const arr = Object.keys(ks).map(db => ({ name: db, value: Number(ks[db].keys || 0) }))
    return {
      tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
      legend: { show: false },
      series: [
        {
          type: 'pie',
          radius: ['60%', '80%'],
          label: { show: true, formatter: '{b}: {d}%' },
          data: arr,
        },
      ],
    }
  })
  // Keyspace分布 柱状图
  const keyspaceBarOption = computed(() => {
    const ks = data.value.keyspaceStats || {}
    const dbs = Object.keys(ks)
    return {
      tooltip: { trigger: 'axis' },
      legend: { data: ['键数', '过期'] },
      xAxis: { type: 'category', data: dbs },
      yAxis: { type: 'value' },
      series: [
        {
          name: '键数',
          type: 'bar',
          data: dbs.map(db => Number(ks[db].keys || 0)),
          itemStyle: { color: '#0057b8' },
          barWidth: 18,
        },
        {
          name: '过期',
          type: 'bar',
          data: dbs.map(db => Number(ks[db].expires || 0)),
          itemStyle: { color: '#faad14' },
          barWidth: 18,
        },
      ],
      grid: { left: 20, right: 20, top: 30, bottom: 20 },
    }
  })

  // CPU 折线图
  const cpuLineOption = computed(() => {
    const stats = cpuStats.value
    return {
      tooltip: { trigger: 'axis' },
      legend: { data: ['系统CPU', '用户CPU'] },
      xAxis: { type: 'category', data: ['当前'] },
      yAxis: { type: 'value' },
      series: [
        {
          name: '系统CPU',
          type: 'line',
          data: [Number(stats.usedCpuSys || 0)],
          itemStyle: { color: '#0057b8' },
        },
        {
          name: '用户CPU',
          type: 'line',
          data: [Number(stats.usedCpuUser || 0)],
          itemStyle: { color: '#36cfc9' },
        },
      ],
      grid: { left: 20, right: 20, top: 30, bottom: 20 },
    }
  })
  // 网络 折线图
  const networkLineOption = computed(() => {
    const stats = networkStats.value
    return {
      tooltip: { trigger: 'axis' },
      legend: { data: ['输入Kbps', '输出Kbps'] },
      xAxis: { type: 'category', data: ['当前'] },
      yAxis: { type: 'value' },
      series: [
        {
          name: '输入Kbps',
          type: 'line',
          data: [Number(stats.instantaneousInputKbps || 0)],
          itemStyle: { color: '#0057b8' },
        },
        {
          name: '输出Kbps',
          type: 'line',
          data: [Number(stats.instantaneousOutputKbps || 0)],
          itemStyle: { color: '#faad14' },
        },
      ],
      grid: { left: 20, right: 20, top: 30, bottom: 20 },
    }
  })

  // 命令统计Top10 柱状图（调用数）
  const commandCallBarOption = computed(() => {
    const cs = data.value.commandStats || {}
    const arr = Object.keys(cs)
      .map(cmd => ({ cmd, calls: Number(cs[cmd].calls || 0) }))
      .sort((a, b) => b.calls - a.calls)
      .slice(0, 10)
    return {
      tooltip: { trigger: 'axis' },
      xAxis: { type: 'category', data: arr.map(i => i.cmd) },
      yAxis: { type: 'value' },
      series: [
        {
          name: '调用数',
          type: 'bar',
          data: arr.map(i => i.calls),
          itemStyle: { color: '#0057b8' },
          barWidth: 22,
        },
      ],
      grid: { left: 20, right: 20, top: 30, bottom: 20 },
    }
  })
  // 命令统计Top10 柱状图（耗时）
  const commandUsecBarOption = computed(() => {
    const cs = data.value.commandStats || {}
    const arr = Object.keys(cs)
      .map(cmd => ({ cmd, usec: Number(cs[cmd].usec || 0) }))
      .sort((a, b) => b.usec - a.usec)
      .slice(0, 10)
    return {
      tooltip: { trigger: 'axis' },
      xAxis: { type: 'category', data: arr.map(i => i.cmd) },
      yAxis: { type: 'value' },
      series: [
        {
          name: '总耗时',
          type: 'bar',
          data: arr.map(i => i.usec),
          itemStyle: { color: '#faad14' },
          barWidth: 22,
        },
      ],
      grid: { left: 20, right: 20, top: 30, bottom: 20 },
    }
  })

  const fetchData = async () => {
    const res = await getRedisMonitorStatus()
    if (res.data && res.data.code === 200) {
      data.value = res.data.data || {}
    }
  }

  function startTimer() {
    if (timer.value) return
    fetchData()
    timer.value = setInterval(fetchData, 1000)
  }
  function stopTimer() {
    if (timer.value) {
      clearInterval(timer.value)
      timer.value = null
    }
  }

  onMounted(startTimer)
  onActivated(startTimer)
  onUnmounted(stopTimer)
  onDeactivated(stopTimer)
</script>

<style scoped>
  .redis-monitor-root {
    padding: 0 8px;
    background: var(--theme-background);
    min-height: 100vh;
    transition: all 0.3s ease;
  }
  
  .overview-row {
    margin-bottom: 0;
  }
  
  .overview-card,
  .group-card,
  .section-card {
    background: var(--theme-surface) !important;
    border: 1px solid var(--theme-border) !important;
    box-shadow: 0 2px 8px var(--theme-shadow);
    border-radius: 12px !important;
    color: var(--theme-text) !important;
    transition: all 0.3s ease;
  }
  
  .card-title {
    color: var(--theme-primary);
    font-size: 15px;
    font-weight: 500;
    margin-bottom: 4px;
    line-height: 1.2;
    transition: color 0.3s ease;
  }
  
  .card-value {
    color: var(--theme-text);
    font-size: 15px;
    font-family: 'JetBrains Mono', 'Consolas', 'Roboto Mono', monospace;
    font-weight: bold;
    line-height: 1.3;
    text-align: left;
    word-break: break-all;
    max-width: 100%;
    min-width: 0;
    display: block;
    white-space: pre-line;
    transition: color 0.3s ease;
  }
  
  .group-row {
    margin-top: 4px;
  }
  
  .group-card {
    background: var(--theme-surface) !important;
    border: 1px solid var(--theme-border) !important;
    box-shadow: 0 2px 8px var(--theme-shadow);
    border-radius: 12px !important;
    color: var(--theme-text) !important;
    min-height: 150px;
    padding: 8px 8px;
    transition: all 0.3s ease;
  }
  
  .chart-area {
    min-height: 90px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 2px;
  }
  
  .stat-row {
    margin-bottom: 0;
    font-size: 13px;
    line-height: 1.5;
  }
  
  .stat-label {
    color: var(--theme-textSecondary);
    transition: color 0.3s ease;
  }
  
  .stat-value {
    color: var(--theme-primary);
    font-family: 'JetBrains Mono', 'Consolas', 'Roboto Mono', monospace;
    word-break: break-all;
    transition: color 0.3s ease;
  }
  
  .section-card {
    background: var(--theme-surface) !important;
    border: 1px solid var(--theme-border) !important;
    box-shadow: 0 2px 12px var(--theme-shadow);
    border-radius: 14px !important;
    color: var(--theme-text) !important;
    margin-bottom: 0;
    margin-top: 0;
    padding: 0 0 8px 0 !important;
    transition: all 0.3s ease;
  }
  
  :deep(.ant-table) {
    background: none !important;
  }
  
  :deep(.ant-table-thead > tr > th) {
    background: var(--theme-background) !important;
    color: var(--theme-primary) !important;
    font-weight: 500;
    font-size: 14px;
    transition: all 0.3s ease;
  }
  
  :deep(.ant-table-tbody > tr > td) {
    background: var(--theme-surface) !important;
    color: var(--theme-text) !important;
    font-size: 13px;
    white-space: pre-line !important;
    word-break: break-all !important;
    transition: all 0.3s ease;
  }
  
  :deep(.ant-table-row:hover) > td {
    background: var(--theme-primary) !important;
    color: var(--theme-surface) !important;
  }

  /* 确保所有元素都使用主题色 */
  .redis-monitor-root * {
    transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
  }
</style>
